package com.yunfeisoft.excel.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.applet.utils.Constants;
import com.applet.utils.KeyUtils;
import com.applet.utils.SpringContextHelper;
import com.yunfeisoft.business.dao.inter.*;
import com.yunfeisoft.business.model.*;
import com.yunfeisoft.business.service.inter.CodeBuilderService;
import com.yunfeisoft.utils.PinyinUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ProductExcelListener extends AnalysisEventListener<Product> {

    private static final Logger logger = LoggerFactory.getLogger(ProductExcelListener.class);

    private List<Product> list = new ArrayList<Product>();
    private String orgId;
    private String userId;

    public ProductExcelListener(String orgId, String userId) {
        this.orgId = orgId;
        this.userId = userId;
    }

    /**
     * 这个每一条数据解析都会来调用
     *
     * @param product
     * @param analysisContext
     */
    @Override
    public void invoke(Product product, AnalysisContext analysisContext) {
        if (StringUtils.isBlank(product.getName())/*
                || StringUtils.isBlank(product.getUnit())
                || product.getStock() == null*/) {
            return;
        }

        product.setId(KeyUtils.getKey());
        product.setOrgId(orgId);
        product.setCreateId(userId);
        product.setModifyId(userId);
        product.setStock(product.getStock() == null ? BigDecimal.ZERO : product.getStock());
        product.setShortageLimit(product.getShortageLimit() == null ? BigDecimal.ZERO : product.getShortageLimit());
        product.setBacklogLimit(product.getBacklogLimit() == null ? BigDecimal.ONE : product.getBacklogLimit());
        product.setBuyPrice(product.getBuyPrice() == null ? BigDecimal.ZERO : product.getBuyPrice());
        product.setSalePrice(product.getSalePrice() == null ? BigDecimal.ZERO : product.getSalePrice());
        product.setMemberPrice(product.getMemberPrice() == null ? BigDecimal.ZERO : product.getMemberPrice());
        product.setTradePrice(product.getTradePrice() == null ? BigDecimal.ZERO : product.getTradePrice());
        product.setPinyinCode(StringUtils.isBlank(product.getPinyinCode()) ? PinyinUtils.getPinYinHeadChar(product.getName()) : product.getPinyinCode());
        list.add(product);
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param analysisContext
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        //不存在的供应商 自动添加
        Map<String, Supplier> supplierMap = new HashMap<>();
        //已存在的供应商
        Map<String, String> existSupplierMap = new HashMap<>();

        //不存在的类别 自动添加
        Map<String, ProductCategory> productCategoryMap = new HashMap<>();
        //已存在的类别
        Map<String, String> existProductCategoryMap = new HashMap<>();

        ProductCategoryDao productCategoryDao = SpringContextHelper.getBean(ProductCategoryDao.class);
        SupplierDao supplierDao = SpringContextHelper.getBean(SupplierDao.class);
        CodeBuilderService codeBuilderService = SpringContextHelper.getBean(CodeBuilderService.class);
        WarehouseDao warehouseDao = SpringContextHelper.getBean(WarehouseDao.class);
        //默认仓库
        Warehouse warehouse = warehouseDao.loadDefault(orgId);

        final List<WarehouseProduct> newWarehouseProductList = new ArrayList<>();

        for (Product product : list) {
            WarehouseProduct warehouseProduct = new WarehouseProduct();
            warehouseProduct.setProductId(product.getId());
            warehouseProduct.setBacklogLimit(product.getBacklogLimit());
            warehouseProduct.setShortageLimit(product.getShortageLimit());
            warehouseProduct.setStock(product.getStock());
            warehouseProduct.setInitStock(product.getStock());
            warehouseProduct.setWarehouseId(warehouse.getId());
            newWarehouseProductList.add(warehouseProduct);

            String categoryName = product.getCategoryName();
            if (StringUtils.isNotBlank(categoryName)) {
                String categoryId = existProductCategoryMap.get(categoryName);
                if (StringUtils.isBlank(categoryId)) {
                    ProductCategory productCategory = productCategoryMap.get(categoryName);
                    if (productCategory != null) {
                        categoryId = productCategory.getId();
                    }
                }
                if (StringUtils.isBlank(categoryId)) {
                    List<ProductCategory> productCategoryList = productCategoryDao.queryByName(orgId, categoryName);
                    if (CollectionUtils.isEmpty(productCategoryList)) {
                        String code = codeBuilderService.generateCode("PRODUCT_CATEGORY_" + Constants.ROOT, 2, orgId);

                        ProductCategory productCategory = new ProductCategory();
                        productCategory.setId(KeyUtils.getKey());
                        productCategory.setOrgId(orgId);
                        productCategory.setName(categoryName);
                        productCategory.setParentId(Constants.ROOT);
                        productCategory.setIdPath(productCategory.getId());
                        productCategory.setCode(code);
                        productCategory.setNamePath(categoryName);
                        productCategory.setPinyinCode(PinyinUtils.getPinYinHeadChar(categoryName));
                        productCategory.setCreateId(userId);
                        productCategory.setModifyId(userId);

                        productCategoryMap.put(categoryName, productCategory);
                        categoryId = productCategory.getId();
                    } else {
                        categoryId = productCategoryList.get(0).getId();
                        existProductCategoryMap.put(categoryName, categoryId);
                    }
                }
                product.setCategoryId(categoryId);
            }

            String supplierName = product.getSupplierName();
            if (StringUtils.isNotBlank(supplierName)) {
                String supplierId = existSupplierMap.get(supplierName);
                if (StringUtils.isBlank(supplierId)) {
                    Supplier supplier = supplierMap.get(supplierName);
                    if (supplier != null) {
                        supplierId = supplier.getId();
                    }
                }

                if (StringUtils.isBlank(supplierId)) {
                    List<Supplier> supplierList = supplierDao.queryByName(orgId, supplierName);
                    if (CollectionUtils.isEmpty(supplierList)) {
                        String code = codeBuilderService.generateCode("SUPPLIER", 4, orgId);

                        Supplier supplier = new Supplier();
                        supplier.setId(KeyUtils.getKey());
                        supplier.setOrgId(orgId);
                        supplier.setName(supplierName);
                        supplier.setBalance(BigDecimal.ZERO);
                        supplier.setPinyinCode(PinyinUtils.getPinYinHeadChar(supplierName));
                        supplier.setCode(code);
                        supplier.setCreateId(userId);
                        supplier.setModifyId(userId);

                        supplierMap.put(supplierName, supplier);
                        supplierId = supplier.getId();
                    } else {
                        supplierId = supplierList.get(0).getId();
                        existSupplierMap.put(supplierName, supplierId);
                    }
                }
                product.setSupplierId(supplierId);
            }
        }

        ProductDao productDao = SpringContextHelper.getBean(ProductDao.class);
        WarehouseProductDao warehouseProductDao = SpringContextHelper.getBean(WarehouseProductDao.class);
        TransactionTemplate transactionTemplate = SpringContextHelper.getBean(TransactionTemplate.class);
        transactionTemplate.execute(new TransactionCallback<Integer>() {
            @Override
            public Integer doInTransaction(TransactionStatus transactionStatus) {
                warehouseProductDao.batchInsert(newWarehouseProductList);
                productDao.batchInsert(list);

                for (Map.Entry<String, Supplier> entry : supplierMap.entrySet()) {
                    supplierDao.insert(entry.getValue());
                }

                for (Map.Entry<String, ProductCategory> entry : productCategoryMap.entrySet()) {
                    productCategoryDao.insert(entry.getValue());
                }
                return 1;
            }
        });
    }
}
